iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 19
0
AI & Data

Knock Knock! Deep Learning系列 第 19

Day 18 / DL x CV / 圖像與 CNN

  • 分享至 

  • xImage
  •  

Day 10 我們用 PyTorch 介紹過 MNIST 手寫數字辨識。當時用的簡單模型就是 Convoluation Neural Network (CNN),常用在抽取圖像特徵,搭配 pooling layer 減少 overfitting 的機會。等了這麼久,終於要來真正認識 CNN 的架構以及他跟圖像的結合了。

Motivation

一張圖片其實挺大的。就算是 MNIST 裡的手寫數字圖,28 x 28 pixels 還只有一個 color channel,就已經有 784 個不同的特徵了。RNN 在每個 timestep 接收的文字轉成 word vector 可能不過 300 的大小,一張這麼小的圖片當作 model 的 input 就已經是文字的兩三倍負擔,遑論正常大小和 RGB 3 個 color channel 的 image input 會有多驚人!

如果想要拿這麼大的 image data 來訓練 neural network,那 fully-connected layer 肯定是招架不住,因為 hidden layer 每個 node 都要連接 input 的每個維度,parameter 的數量會非常龐大。

但仔細想一下,每個 hidden node 目標是學習到對目標任務有用的某個特徵,那有需要讓每個 hidden node 都連接到整張圖片的所有角落嗎?假設我們在做車的種類判別,那可能會需要提取車的輪廓、車的標誌、車的顏色等等特徵,但這些特徵通常都只是整張圖片的一小部分。也就是說,我們需要一個架構能夠提取局部特徵就好,來減低 network 的負擔。

CNN 就是這樣一個適合圖像的 model。讓我們來看一看 CNN 怎麼提取局部特徵,並有效降低所需要的 parameter 數量。

CNN

一個典型的 CNN 會有這些 layer:

  1. Input layer:W x H x C,寬 x 高 x channel 的大小
  2. Convolutional layer:會有很多 filter 掃過圖片,提取局部特徵
  3. ReLU layer:activation
  4. Pooling layer:downsampling,集合小局部的特徵成為大局部的特徵
  5. Fully-connected layer:連接到 ouput 做 softmax 以進行 classification

2 - 4 可以重複很多層,中間加入 normalization layer 亦可。

在介紹重點層之前,要知道 CNN 跟一般 fully-connected netowrk 不一樣的是他的 3D input 讓中間幾層也都是 3D 的形狀,weight x height x depth。Depth 可以想成 feature 數量,每一個 feature 都來自上一層 weight x height 的某個局部以及 depth 的全部。這在思考時需要稍加留意。

NN vs CNN
—— 左:一般 neural network。右:CNN。[2]

接下來主要介紹 convolutional layer 和 pooling layer。

Convolutional Layer

每層 conv layer 都由幾個 filter 或稱 kernel 作用在 input 上形成一個 activation map 作為下一層的 feature。每個 filter 會掃過整個 input 一一提取局部特徵,且 filter 的 depth 會和 input 一樣。

我們拿 32 x 32 x 3 的 input 和 5 x 5 x 3 的 filter 為例,一個 filter 和一張 image 做 convolution 大概是這樣:

convolution
—— Convolution with 1 filter。[1]

一個 filter 其實就是一組 weights W,將這個 input 局部 https://chart.googleapis.com/chart?cht=tx&chl=X_i 的每個 node 連接到 hidden node,進行 https://chart.googleapis.com/chart?cht=tx&chl=W%20%5Codot%20X_i%20%2B%20b 的運算(https://chart.googleapis.com/chart?cht=tx&chl=%5Codot 是 element-wise multiplication)。其實跟之前見過的 fully-connected layer 很像,只是每個 hidden node 連接到更小的 input 範圍。我們稱這個局部 https://chart.googleapis.com/chart?cht=tx&chl=X_i 為這個 hidden node 的 receptive field

而在 input 邊緣的部分,因為比較少被重複掃過,整個 activation map 也會小一點。以這組的大小來說 output 會是 28 x 28。

不懂為什麼的話可以拿紙畫一下 7 x 7 的 image 有幾個 3 x 3 大小的小正方形,也就會觀察出 output 大小會是 https://chart.googleapis.com/chart?cht=tx&chl=(w%20-%20f%20%2B%201)%20%5Ctimes%20(h%20-%20f%20%2B%201)https://chart.googleapis.com/chart?cht=tx&chl=w%20%5Ctimes%20h 是 input 大小,f 是 filter 大小。

這邊可以觀察到整個 filter 是重複利用的,所以一個 5 x 5 x 3 的 filter 只會有 75 個 weights!跟之前相比有效率非常多。

為了對每個局部學習不一樣的特徵,我們會有很多不同的 filter 重複一樣的步驟:

different filters
—— Convolution with multiple filters。[1]

假如有 k 個 filter,就會形成 k 個 activation map,下一層的 depth 也是 k。這一層的 parameters 不算 bias 的話只會有 75 k 個,相當節能減碳。

Stride and Padding

Filter 掃過去的過程可以有些不同設定,例如從原本一次移一格變成兩格,這個大小稱為 stride

而在邊角的時候也不一定要 filter 在 input 上,可以選擇讓 filter 超過邊界,而在超過的 input 加 padding。Padding 時還可以選擇要都填 0、延伸邊界、或其他一些選擇。

padding
—— Zero-padding。[1]

另外還有一些不常見的設定,有興趣可以參考 PyTorch Conv2d。可以視任務特性選擇這些設定,或是用預設大概也不會差太多。不過記得這些設定也會影響 output size 的算法!

Pooling Layer

Pooling 通常出現在 activation 之後,進入下個 convolutional layer 之前。為了減少 parameters 數量以避免 overfitting,會先用 pooling 把局部結果集合起來,決定更大局部的大致特徵。另外 pooling 是 depth-wise 的,也就是每個 depth channel 不會和其他 channel 互動,自己做自己的 pooling。

max pooling 來說,假設 filter size 是 2 x 2,stride 是 2,那大概會長這樣:

max pooling
—— Max pooling。[1]

原本 input 每 2 x 2 個局部結果取 max 當作大區域的代表,而 output 也減少了 2 x 2 倍。注意到 pooling layer 其實沒有 parameter 需要訓練,可以把它想成單純的 function。

除了 max pooling,另外常見的還有 average pooling 取平均。那麼兩者要怎麼選擇呢?因為 max pooling 只選了最大的 activation,他會喪失比較多訊息,但如果你的任務主要就是只想保留顯著的特徵,那麼 max pooling 是個好選擇。反之如果你的主要目標需要藉由提取比較完整的全局特徵來達成,那麼 average pooling 可能就會表現比較好。

Layer 疊疊樂

介紹完後,應該大致知道為什麼 convolutional layer 可以提取局部特徵而且能減少 network parameter,還有 pooling layer 可以藉由篩選局部最有用的特徵縮減 output 大小以避免 overfitting。

到這邊已經可以建立自己的 network 架構了。其實要建立一個還不錯的 CNN 可以很無腦,大致上就循環 CONV-RELU-POOL 接到 FC

INPUT - [(CONV-RELU) * N - POOL?] * M - (FC - RELU) * K - SOFTMAX

早期 CNN 的架構設計反而比不上把他建得更深來得更能讓 performance 飛快提升。之後 performance 比較難快速提升後,才有些比較有趣的架構設計,例如之前提過 ResNet 的 residual,和 GoogleLeNet 的 inception module 等等。有興趣可以看看延伸閱讀的連結。

What is Each Layer Doing?

Network 中每一層都在抽取不同 level 的 abstract feature,這個之前應該有提到。前面幾層會捉摸靠近圖像本身的 generic feature,例如邊角、明暗、線條角度等等。後面幾層慢慢抽絲剝繭,理出跟預測任務最相關的 specific feature,例如人的五官、車的輪胎等等。

Visualize 一下每一層的 output,就能證明這件事:

different levels of features
—— 每層學到不同 level 的 feature。[4]

而把 network 建深而不是建廣的理由,就是因為 higher-level feature 很多其實都來自相同的 lower-level feature,所以一層一層的提取讓這些 feature 可以重複使用,增加效率。相反的,一個很廣但沒幾層的 network,想必每一層都重複提取了很多 low-level 特徵,大部分時候就比較沒效率了。

Checkpoint

  • 把 image 直接當作 fully-connected network 的 input,會有什麼問題?為什麼 CNN 可以避免這種問題?
  • 假設有一層 convolutional layer 有 64 個 filter,每個 filter 大小為 7 x 7 x 3。那麼 input 一張大小為 35 x 35 x 3 的圖片,output 大小為何?假設沒有 padding,stride 為 1。
  • 承上題,不計 bias,這一層有多少 parameters?
  • 假設有一層 max pooling layer,每個 filter 大小為 5 x 5。那麼 input 一張大小為 35 x 35 x 3 的圖片,output 大小為何?假設沒有 padding,stride 為 5。
  • 承上題,不計 bias,這一層有多少 parameters?
  • network structure 圖為 Day 9 做 MNIST 示範的 CNN 架構。圖中標示的大小為 output 大小。請找出 Conv 有多少 filter 以及 filter 的合理設定。同樣的請找出 MaxPool filter 的合理設定。

參考資料

  1. CS231n Lecture Slides: Convolutional Neural Networks
  2. ? CS231n Lecture Notes: Convolutional Neural Networks (CNNs / ConvNets)
  3. CS231n Lecture Slides: CNN Architectures
  4. Convolutional Neural Networks Explained

延伸閱讀

  1. (He et al., 2015) Deep Residual Learning for Image Recognition
  2. (Szegedy et al., 2015) Going Deeper with Convolutions

上一篇
Day 17 / DL x CV / 從 ImageNet 發起的 Data 大戰
下一篇
Day 19 / DL x CV / 文字也有結構,圖像也有序列
系列文
Knock Knock! Deep Learning31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言